<?php

declare(strict_types=1);

namespace App\Controller\Home\User;

use App\Job\CheckJob;
use App\Job\CheckPaid;
use App\Model\BalanceOrder;
use App\Model\Bill;
use App\Model\ChargeDetail;
use App\Model\ChargeOption;
use App\Model\Coupon;
use App\Model\CouponRecord;
use App\Model\Device;
use App\Model\DevicePort;
use App\Model\Distributors;
use App\Model\Feedback;
use App\Model\Order;
use App\Model\RefundBalanceLog;
use App\Model\RefundLog;
use App\Model\Service;
use App\Model\Station;
use App\Model\User;
use App\Services\AdapayService;
use App\Services\BankService;
use App\Services\BspayService;
use App\Services\DeviceService;
use App\Services\Iot\IotService1 as IotService;
use App\Services\OrderQueueService;
use App\Services\PaymentStrategyFactory;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use Hyperf\Context\ApplicationContext;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\HttpServer\Contract\RequestInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Qiniu\Http\Request;
use Trait\ResponseMsg;
use App\Model\Normal;
use Hyperf\Di\Annotation\Inject;
use Util\Common;
use Phper666\JWTAuth\JWT;

use App\Services\Wechat;
use App\Controller\AbstractController;


class UserOrderController extends AbstractController
{
    use ResponseMsg;

    #[inject]
    protected User $user;
    #[inject]
    protected ChargeOption $chargeOption;
    #[inject]
    protected ChargeDetail $chargeDetail;
    #[inject]
    protected CouponRecord $couponRecord;
    #[inject]
    protected Service $service;
    #[inject]
    protected Order $order;

    #[inject]
    protected BankService $bankService;

    #[inject]
    protected OrderQueueService $orderQueueService;

    #[inject]
    protected Coupon $coupon;

    #[inject]
    protected Device $device;

    protected Redis $redis;
    protected Normal $normal;
    protected JWT $jwt;
    protected Wechat $wechat;

    public function __construct()
    {
        $this->jwt = container()->get(JWT::class);
        $this->redis = container()->get(Redis::class);
        $this->normal = container()->get(Normal::class);
        $this->wechat = container()->get(Wechat::class);
    }

    public function orderTest(RequestInterface $request)
    {

        $bankService = new BankService();
        $bankService->createOrder($request);
    }

    public function createTest(RequestInterface $request)
    {
        $id = $request->input('id');
        $lat = $request->input('lat');
        $lng = $request->input('lng');
        $type = $request->input('type');
        if ($type == 'add') {
            Device::addStation($id . '', (float)$lng, (float)$lat);
        }
        if ($type == 'del') {
            Device::removeStation($id);
        }
        return $this->success();
//        $bankService =new BankService();
//        $bankService->createOrder($request);
    }

    /**用户充值余额
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function createBalance(RequestInterface $request): ResponseInterface
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $params = $request->inputs(['money', 'sn', 'pay_type']);
        if ($params['sn']) {
            $device = $this->device->where('sn', $params['sn'])->first();
            if (!$device) {
                return $this->error(1001, '设备编号不存在');
            }
            $save['device_id'] = $device->id;
        }
        $save['number'] = $this->normal->randOrder($info['id']);
        $save['user_id'] = $info['id'];
        $save['fee'] = $params['money'];
        $save['payment_type'] = $params['pay_type'];
        if ($params['pay_type'] == 'wx_lite') {
            $save['payment_type'] = 1;
        }
        try {
            $orderModel = BalanceOrder::create($save);
            if (!$orderModel) {
                return $this->error(code: '1002', msg: '订单创建失败');
            }
            $service = new BspayService();
            $result = $service->createBalance($orderModel);
            $result['number'] = $orderModel->number;
            return $this->success($result);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1001, '操作繁忙 请稍后再试');
        }
    }

    /**创建设备订单
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function createOrder(RequestInterface $request): ResponseInterface
    {
        $params = $request->inputs(['charge_detail_id',
            'charge_option_id', 'fee', 'service_fee', 'service_id',
            'sn', 'port', 'pay_type', 'coupon_record_id', 'return_url']);
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $params['sn'] = trim($params['sn']);
        $device = Device::where('sn', $params['sn'])->with('station')->first();
        if (!$device) {
            return $this->error(code: 1001, msg: '设备编号不存在');
        }
        if (!$device->inline || !$device->fd) {
            return $this->error(code: 1001, msg: '当前设备不在线');
        }
        $this->user->addUseCount($info['id'], $device->id);
        if ($device->is_active != 1) {
            return $this->error(1001, '设备已暂停服务');
        }
        if ($device->station_id <= 0) {
            return $this->error(1001, '设备未分配站点');
        }
        $checkUsing = $this->order->where('device_id', $device->id)
            ->where('channel_number', $params['port'])
            ->whereIn('status', [$this->order::STATUS_USING, $this->order::STATUS_PAID])
            ->first();
        if ($checkUsing) {
            return $this->error(1001, '设备端口正在使用中 请更换其他端口使用');
        }
        $save['distributor_id'] = $device->distributor_id;
        $save['device_id'] = $device->id;
        $save['sn'] = $params['sn'];
        $save['payment_type'] = $params['pay_type'];
        $save['channel_number'] = $params['port'];
        $save['service_fee'] = $params['service_fee'];
        $save['station_id'] = $device->station_id;
//      $save['is_autoload'] = $params['is_autoload'];
        $save['charge_id'] = $params['charge_option_id'];
        if (isset($params['fee']) && $params['fee'] > 0) {
            if (!is_numeric($params['fee']) || $params['fee'] < 1 || $params['fee'] > 100) {
                return $this->error(1001, '自定义金额请输入1-100元之间');
            }
            $save['minutes'] = round($device->max_charge_time ? $device->max_charge_time / 60 : 64800 / 60);
            $save['power_fee'] = $save['fee'] = $params['fee'];
        } else {
            $chargeDetailModel = $this->chargeDetail->where('id', $params['charge_detail_id'])
                ->with('charge')->first();
            $save['power_fee'] = $save['fee'] = $chargeDetailModel->fee;
            $save['charge_detail_id'] = $params['charge_detail_id'];
            if ($chargeDetailModel->charge->type == 2) {
                $save['minutes'] = $chargeDetailModel->minutes;
            } else {
                $save['minutes'] = round($device->max_charge_time ? $device->max_charge_time / 60 : 64800 / 60);
            }
        }
        if ($params['coupon_record_id']) {
            $couponRecord = $this->couponRecord->where('id', $params['coupon_record_id'])->first();
            if (!$couponRecord) {
                return $this->error(1002, '优惠券信息有误');
            }
            if ($couponRecord->used_at) {
                return $this->error(1002, '优惠券已被使用');
            }
            if (time() > strtotime($couponRecord->expires_at)) {
                return $this->error(1002, '优惠券已过期');
            }
            $fillfee = Coupon::where('id', $couponRecord->coupon_id)->value('fee');
            if ($save['fee'] > $fillfee) {
                $save['fee'] = $save['fee'] - $fillfee;
            } else {
                $save['fee'] = 0;
            }
            $save['coupon_record_id'] = $params['coupon_record_id'];
        }
        $save['number'] = $this->normal->randOrder($device->id);
        $save['user_id'] = $info['id'];
        if ($save['payment_type'] == Order::WHITE) {
            $save['fee'] = 0;
        }else{
            $whiteKey ='WHITE_DEVICE_'. $device->station->id;
            $checkWhite = redis()->sMembers($whiteKey);
            if($checkWhite){
                if(in_array($info['id'],$checkWhite)){
                    $params['pay_type'] = Order::WHITE;
                    $save['payment_type'] = Order::WHITE;
                    $save['service_fee'] = 0;
                    $save['fee'] = 0;
                }
            }
        }
        if (!$save['service_fee']) {
            $save['service_fee'] = 0;
        }
        $save['fee'] = $save['fee'] + $save['service_fee'];
        try {
            $orderModel = Order::create($save);
            if (!$orderModel) {
                return $this->error(code: '1002', msg: '订单创建失败');
            }
            if ($params['pay_type'] == Order::BALANCE) {
                $result = $orderModel->balancePay([
                    'return_url' => $params['return_url']
                ]);
                if ($result['code'] != 200) {
                    return $this->error($result['code'], $result['msg']);
                }
                $driver = ApplicationContext::getContainer()->get(DriverFactory::class)->get('check-paid');
                $driver->push(new CheckPaid($save['number']), 15);
            } else {
                if ($orderModel->fee <= 0) {
                    $orderModel->paySuccess();
                    $driver = ApplicationContext::getContainer()->get(DriverFactory::class)->get('check-paid');
                    $driver->push(new CheckPaid($save['number']), 15);
                    return $this->success(['code' => 200, 'msg' => '成功','number'=>$orderModel->number]);
                }
                $service = new BspayService();
                $result = $service->createPayment($orderModel);
                $result['number'] = $orderModel->number;
            }
            return $this->success($result);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1001, $e->getMessage());
        }
    }

    /**余额充值回调
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function balanceNotify(RequestInterface $request)
    {
        $data = $request->all();
        Normal::logger('balance-notify:' . json_encode($data), 'order-queue');
        try {
            if ($data['resp_code'] == "00000000") {
                $responseData = $data['resp_data'];
                if (!is_array($responseData)) {
                    $responseData = json_decode($responseData, true);
                }
                if ($responseData['trans_stat'] == "S" && $responseData['notify_type'] == 2) {
                    $balance = BalanceOrder::where('number', $responseData['mer_ord_id'])->first();
                    $balance->balanceNotify($responseData);
                }
            }
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        } catch (\Exception $e) {
            Normal::logger('balance-notify:' . $e->getMessage() . $e->getTraceAsString(), 'order-queue');
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        }
    }

    /**支付宝余额回调
     * @param RequestInterface $request
     * @return void
     */
    public function aliBalanceNotify(RequestInterface $request)
    {
        $type['pay_type'] = 'alipay_lite';
        $payModel = PaymentStrategyFactory::createPaymentStrategy($type);
        $result = $payModel->balance_notify($request);
        Normal::logger('pay-success-ali---return:' . json_encode($result), 'home');
        return $result;
    }


    public function doRefund(RequestInterface $request)
    {
        Normal::logger('回调结束订单' . json_encode($request->all()), 'home');
        $orderId = $request->input('id');
        $type = $request->input('type', 'stop');
        $order = $this->order->where('id', $orderId)->first();
        $order->use_fee = $request->input('use_fee', 0);
        $order->charge_service = $request->input('charge_service', 0);
        $order->use_elec = $request->input('use_elec', 0);
        $order->minutes = $request->input('minutes', 0);
        $order->power = $request->input('power', 0);
        $order->stop_reason = $request->input('stop_reason', '未知');
        if ($type == 'stop') {
            $order->stop($order->stop_reason);
        } else {
            $order->fail($order->stop_reason);
        }
    }

    /**余额退款回调
     * @param RequestInterface $request
     * @return void
     */
    public function refundBalanceNotify(RequestInterface $request)
    {
        $data = $request->all();
        try {
            if ($data['resp_code'] == "00000000") {
                $responseData = $data['resp_data'];
                if (!is_array($responseData)) {
                    $responseData = json_decode($responseData, true);
                }
                $refund = RefundBalanceLog::where('refund_no', $responseData['mer_ord_id'])
                    ->with('order')->first();
                if ($responseData['trans_stat'] == "S") {
                    $refund->order->refundSuccess($responseData);
                    $refund->status = 1;
                    $refund->refund_time = $responseData['end_time'];
                    $refund->save();
                }
                if ($responseData['trans_stat'] == "F") {
                    $refund->status = 2;
                    $refund->save();
                }
            }
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        } catch (\Exception $e) {
            Normal::logger('refund-notify:' . $e->getMessage() . $e->getTraceAsString(), 'order-queue');
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        }
    }

//    /**支付宝余额退款回调
//     * @param RequestInterface $request
//     * @return void
//     */
//    public function aliRefundBalance(RequestInterface $request)
//    {
//        $type['pay_type'] = 'alipay_lite';
//        $payModel = PaymentStrategyFactory::createPaymentStrategy($type);
//        $payModel->refundBalanceNotify($request);
//    }

    /**微信支付回调
     * @param RequestInterface $request
     * @return void
     */
    public function wxNotify(RequestInterface $request)
    {
        $data = $request->all();
        Normal::logger('wx-notify:' . json_encode($data), 'order-queue');
        try {
            if ($data['resp_code'] == "00000000") {
                $responseData = $data['resp_data'];
                if (!is_array($responseData)) {
                    $responseData = json_decode($responseData, true);
                }
                if ($responseData['trans_stat'] == "S" && $responseData['notify_type'] == 2) {
                    $order = Order::where('number', $responseData['mer_ord_id'])
                        ->with('device')
                        ->with('charge')->first();
                    $order->payMent($responseData);
                    $driver = ApplicationContext::getContainer()->get(DriverFactory::class)->get('check-paid');
                    $driver->push(new CheckPaid($responseData['mer_ord_id']), 15);
                }
            }
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        } catch (\Exception $e) {
            Normal::logger('wx-notify:' . $e->getMessage() . $e->getTraceAsString(), 'order-queue');
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        }
    }

    public function refundNotify(RequestInterface $request)
    {
        $data = $request->all();
        Normal::logger('refund-notify:' . json_encode($data), 'order-queue');
        try {
            if ($data['resp_code'] == "00000000") {
                $responseData = $data['resp_data'];
                if (!is_array($responseData)) {
                    $responseData = json_decode($responseData, true);
                }
                $refund = RefundLog::where('refund_no', $responseData['mer_ord_id'])
                    ->with('order')->first();
                if ($responseData['trans_stat'] == "S") {
                    $refund->order->refundSuccess($responseData);
                    $refund->status = 1;
                    $refund->refund_time = $responseData['end_time'];
                    $refund->save();
                    $refund->notifySomething();
                }
                if ($responseData['trans_stat'] == "F") {
                    $refund->status = 2;
                    $refund->save();
                }
            }
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        } catch (\Exception $e) {
            Normal::logger('refund-notify:' . $e->getMessage() . $e->getTraceAsString(), 'order-queue');
            return \Hyperf\Context\ApplicationContext::getContainer()
                ->get(\Hyperf\HttpServer\Contract\ResponseInterface::class)
                ->raw('success');
        }
    }

    /**支付宝支付回调
     * @param RequestInterface $request
     * @return void
     */
    public function aliNotify(RequestInterface $request)
    {
        $type['pay_type'] = 'alipay_lite';
        $payModel = PaymentStrategyFactory::createPaymentStrategy($type);
        return $payModel->notify($request);
    }


    /**微信退款回调
     * @param RequestInterface $request
     * @return void
     */
    public function wxRefund(RequestInterface $request)
    {
        $type['pay_type'] = 'wx_lite';
        $payModel = PaymentStrategyFactory::createPaymentStrategy($type);
        return $payModel->refundNotify($request);
    }

    /**支付宝退款回调
     * @param RequestInterface $request
     * @return void
     */
//    public function aliRefund(RequestInterface $request)
//    {
//        $type['pay_type'] = 'alipay_lite';
//        $payModel = PaymentStrategyFactory::createPaymentStrategy($type);
//        $payModel->refundNotify($request);
//    }


//    /**
//     * 微信支付回调
//     * @param RequestInterface $request
//     * @return ResponseInterface
//     * @throws ContainerExceptionInterface
//     * @throws NotFoundExceptionInterface
//     */
//    public function wxNotify(RequestInterface $request):ResponseInterface{
//        try {
//            $params = $request->all();
//            $data = json_decode($params['biz_content'],true);
//            if($this->redis->exists('notify_order_cache_'.$data['out_trade_no'])){
//                $data['msg'] ='success';
//                return $this->success($data['msg']);
//            }
//            $this->redis->setex('notify_order_cache_'.$data['out_trade_no'],60*5,1);
//            $orderModel = $this->order->where('number',$data['out_trade_no'])->first();
//            $orderModel->payMent($data);
//            $driver = ApplicationContext::getContainer()->get(DriverFactory::class)->get('check-paid');
//            $driver->push(new CheckPaid($data['out_trade_no']), 30);
//            $data['msg'] ='success';
//            return $this->success($data['msg']);
//        } catch (\Exception $e) {
//            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
//            return $this->error(1001, $e->getMessage());
//        }
//    }
//
//
//    public function aliNotify(RequestInterface $request):ResponseInterface{
//        try {
//            $params = $request->all();
//            $data = json_decode($params['biz_content'],true);
//            if($this->redis->exists('notify_order_cache_'.$data['out_trade_no'])){
//                return $this->success();
//            }
//            $this->redis->setex('notify_order_cache_'.$data['out_trade_no'],60*5,1);
//            $orderModel = $this->order->where('number',$data['out_trade_no'])->first();
//            $orderModel->payMent($data);
//            $driver = ApplicationContext::getContainer()->get(DriverFactory::class)->get('check-paid');
//            $driver->push(new CheckPaid($data['out_trade_no']), 30);
//            $data['msg'] ='success';
//            return $this->success($data['msg']);
//        } catch (\Exception $e) {
//            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
//            return $this->error(1001, $e->getMessage());
//        }
//    }

//    /**退款回调
//     * @param RequestInterface $request
//     * @return void
//     */
//    public function refund(RequestInterface $request):ResponseInterface{
//        try {
//            $params = $request->all();
//            $data = json_decode($params['data'],true);
//            $orderModel = $this->order->where('number',$data['payment_order_no'])->first();
//            if($this->redis->exists('notify_return_cache_'.$data['id'])){
//                return $this->success();
//            }
//            if($data['status'] == 'succeeded'){
//                $this->redis->setex('notify_return_cache_'.$data['id'],60*5,1);
//                $orderModel->refundSuccess($data);
//            }
//            return $this->success();
//        } catch (\Exception $e) {
//            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
//            return $this->error(1001, $e->getMessage());
//        }
//    }
//
//    /**安心充退款回调
//     * @param RequestInterface $request
//     * @return ResponseInterface
//     * @throws ContainerExceptionInterface
//     * @throws NotFoundExceptionInterface
//     */
//    public function refundService(RequestInterface $request):ResponseInterface{
//        try {
//            $params = $request->all();
//            $data = json_decode($params['data'],true);
//            $orderModel = $this->order->where('number',$data['payment_order_no'])->first();
//            if($this->redis->exists('notify_service_return_cache_'.$data['id'])){
//                return $this->success();
//            }
//            if($data['status'] == 'succeeded'){
//                $this->redis->setex('notify_service_return_cache_'.$data['id'],60*5,1);
//                $orderModel->serviceRefundSuccess($data);
//            }
//            return $this->success();
//        } catch (\Exception $e) {
//            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
//            return $this->error(1001, $e->getMessage());
//        }
//    }

    /**
     * @param RequestInterface $request
     * @return ResponseInterface|void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function refundOrder(RequestInterface $request)
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $orderNo = $request->input('order_no');
        if (!$orderNo) {
            return $this->error(1001, '订单号不能为空');
        }
        $orderModel = $this->order->where('number', $orderNo)->where('user_id', $info['id'])->first();
        if (!$orderModel) {
            return $this->error(1001, '订单不存在');
        }
        if ($orderModel->status != Order::STATUS_PAID && $orderModel->status != Order::STATUS_USING) {
            return $this->error(1001, '支付成功的订单才可退款');
        }
        try {
            Normal::logger('订单退款被调用', 'order-queue', 'error');
            $orderModel->fail('订单超时异常', true);
            return $this->success(msg: "充电异常，请重新操作！\n已支付费用，系统自动退还。");
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1002, '操作繁忙 请稍后重试');
        }
    }


    /**自定义退款回调
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function refundNormal(RequestInterface $request): ResponseInterface
    {
        try {
            $params = $request->all();
            $data = json_decode($params['data'], true);
            $orderModel = $this->order->where('number', $data['payment_order_no'])->first();
            if ($this->redis->exists('notify_normal_return_cache_' . $data['id'])) {
                return $this->success();
            }
            if ($data['status'] == 'succeeded') {
                $this->redis->setex('notify_normal_return_cache_' . $data['id'], 60 * 5, 1);
                $orderModel->normalRefundSuccess($data);
            }
            return $this->success();
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1001, $e->getMessage());
        }
    }


    /**获取用户正在充电列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function usingList(RequestInterface $request): ResponseInterface
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $data = $this->order->where('user_id', $info['id'])
            ->with('device.port')
            ->with('detail')
            ->where('status', $this->order::STATUS_USING)
            ->get();
        return $this->success($data);
    }

    /**我的订单列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function myOrderList(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->user->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }
            $page = $request->inputs(['start', 'end', 'page', 'limit', 'status']);
            $query = $this->order->where('user_id', $info['id'])
                ->where(function ($query) use ($page) {
                    if (array_key_exists('start', $page) && $page['start']) {
                        $query->where('created_at', '>=', $page['start']);
                    }
                    if (array_key_exists('end', $page) && $page['end']) {
                        $query->where('created_at', '<=', $page['end']);
                    }
                    if (array_key_exists('status', $page) && $page['status']) {
                        $query->where('status', $page['status']);
                    }
                })
                ->with([
                    'station' => function ($query) {
                        $query->select('id', 'name'); // 只选择 distributor 的 id 和 phone 字段
                    },
                    'distributor' => function ($query) {
                        $query->select('id', 'customer_service_phone'); // 只选择 distributor 的 id 和 phone 字段
                    },
                    'charge',
                    'charge.time_children',
                    'charge.power_children',
                    'charge.service_children',
                    'detail'
                ]);
            $data['total'] = $query->count();
            $data['list'] = $query->offset(($page['page'] - 1) * $page['limit'])
                ->limit($page['limit'])
                ->orderBy('id', 'desc')->get();
            return $this->success($data);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1001, $e->getMessage());
        }
    }

    /**余额订单
     * @param RequestInterface $request
     * @return ResponseInterface
     */
    public function balanceList(RequestInterface $request): ResponseInterface
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $page = $request->inputs(['page', 'limit']);
        $data['list'] = BalanceOrder::where('user_id', $info['id'])
            ->offset(($page['page'] - 1) * $page['limit'])
            ->limit($page['limit'])
            ->orderBy('id', 'desc')
            ->get();
        $data['total'] = BalanceOrder::where('user_id', $info['id'])->count();
        return $this->success($data);
    }


    /**获取套餐详细信息
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getChargeOrder(RequestInterface $request): ResponseInterface
    {
        try {
            $chargeId = $request->input('charge_id');
            if (!$chargeId) {
                return $this->error(1001, '套餐id不能为空');
            }
            $charge = $this->chargeOption->where('id', $chargeId)
                ->with('time_children', 'power_children', 'service_children')
                ->first();
            if (!$charge) {
                return $this->error(1001, '套餐信息不存在');
            }
            return $this->success($charge);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1001, $e->getMessage());
        }
    }

    /**结束设备充电
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function stopOrder(RequestInterface $request): ResponseInterface
    {
        $order_no = $request->input('order_no', 0, 'int');
        $orderModel = $this->order->with('device')
            ->where('number', $order_no)->first();
        if (!$orderModel) {
            return $this->error('订单不存在');
        }
        if (!$orderModel->device->fd) {
            $orderModel->offStop('设备离线结单');
            return $this->success();
        }
        $data = [
            'fd' => $orderModel->device->fd,
            'sn' => $orderModel->device->sn,
            'channel_number' => $orderModel->channel_number,
            'number' => $orderModel->number,
            'balance' => 0
        ];
        $response = DeviceService::postTcp('/tcp/stop', $data);
        $responseData = json_decode($response->getBody()->getContents(), true);
        if ($response->getStatusCode() == 200) {
            if ($responseData['code'] == 200) {
                Db::commit();
                return $this->success(msg: '关闭发送成功');
            } else {
                Db::rollBack();
                return $this->error(1001, $responseData['msg'] ?? '关闭发送失败');
            }
        } else {
            Db::rollBack();
            return $this->error(1001, '关闭发送失败: ' . ($responseData['message'] ?? '未知错误'));
        }
    }

    /**结束订单
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function failOrder(RequestInterface $request): ResponseInterface
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $orderNo = $request->input('order_no');
        if (!$orderNo) {
            return $this->error(1001, '订单号不能为空');
        }
        $orderModel = $this->order->where('number', $orderNo)->where('user_id', $info['id'])->first();
        if (!$orderModel) {
            return $this->error(1001, '订单不存在');
        }
        if ($orderModel->status != Order::STATUS_PAID) {
            return $this->error(1001, '支付成功的订单才可退款');
        }
        try {
            $orderModel->fail('订单超时退款');
            return $this->success(msg: "充电异常，请重新扫码开启！\n已支付费用，系统自动退还。");
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1002, '操作繁忙 请稍后重试');
        }
    }


    /**检查订单状态
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function checkOrderStatus(RequestInterface $request): ResponseInterface
    {
        try {
            $orderNo = $request->input('order_no');
            $orderModel = $this->order->where('number', $orderNo)
                ->with('detail')
                ->first();
            if (!$orderModel) {
                return $this->error(1001, '订单不存在');
            }

            if ($orderModel) {
                $orderModel->now = date('Y-m-d H:i:s', time());
            }
            return $this->success($orderModel);
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1001, $e->getMessage());
        }
    }

    /**检查余额充值
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function checkBalanceStatus(RequestInterface $request): ResponseInterface
    {
        $orderNo = $request->input('order_no');
        $orderModel = BalanceOrder::where('number', $orderNo)
            ->first();
        if (!$orderModel) {
            return $this->error(1001, '订单不存在');
        }
        if ($orderModel) {
            $orderModel->now = date('Y-m-d H:i:s', time());
        }
        return $this->success($orderModel);
    }

    /**反馈建议
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function feedBack(RequestInterface $request): ResponseInterface
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $params = $request->inputs(['order_id', 'name', 'phone', 'content', 'images']);

        if (!$params['order_id']) {
            return $this->error(1001, '请选择您要投诉的订单');
        }
        $orderModel = Order::where('id', $params['order_id'])->first();
        $save['order_id'] = $params['order_id'];
        $save['user_id'] = $info['id'];
        $save['name'] = $params['name'];
        $save['phone'] = $params['phone'];
        $save['content'] = $params['content'];
        $save['sn'] = $orderModel->sn;
        $save['channel_number'] = $orderModel->channel_number;
        if($params['images']){
            $save['images'] = json_encode($params['images']);
        }
        try {
            Feedback::create($save);
            return $this->success(msg: '反馈成功 请等待工作人员处理');
        } catch (\Exception $e) {
            Normal::logger($e->getMessage() . $e->getTraceAsString(), 'home');
            return $this->error(1002, '反馈失败 请稍后处理');
        }
    }

    /**反馈订单下拉菜单
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function feedOrderList(RequestInterface $request): ResponseInterface
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $oneMonthAgo = date('Y-m-d', strtotime('-1 month'));

        $data = $this->order->where('user_id', $info['id'])
            ->where('created_at', '>=', $oneMonthAgo)
            ->get(['number', 'sn', 'id', 'status'])->toArray();
        return $this->success($data);
    }

    /**
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function getUseCount(RequestInterface $request): ResponseInterface
    {
        $info = $this->user->getInfo($request);
        if (!$info) {
            return $this->error(code: '400', msg: '登录态失效 请重新登录');
        }
        $list = $this->user->getUseCount($info['id']);
        $data = [];
        foreach ($list as $k => &$v) {
            $device = $this->device->where('id', $k)->with('station')->with('port')->first();
            if ($device) {
                $device->use_count = $v;
                if ($device->station) {
                    $data[] = $device;
                }
//           $device->geo_dist = Device::getGeoDist($lng,$lat,$device->station_id);
            }
        }
        return $this->success($data);
    }

}
